/*
 * Type.h
 *
 *  Created on: Oct 13, 2018
 *      Author: ax
 */

#ifndef INCLUDE_TYPE_H_
#define INCLUDE_TYPE_H_

#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#ifdef USE_XDC
#include <xdc/std.h>
#else
#if defined(_TMS320C6400_PLUS)  \
    || defined(_TMS320C6740)    \
    || defined(_TMS320C6600)
#ifndef USE_XDC
#include <ti/csl/tistdtypes.h>
#endif
#endif
#endif


/* endian */
#define _BE             0x1234
#define _LE             0x4321

#ifndef ENDIAN
#define ENDIAN          _LE
#endif

#ifndef CORE_BITS
#define CORE_BITS       32    //8/16/32/64/?128
#endif


typedef int16_t         Status;
typedef int8_t          SizeS;
typedef int16_t         Size;
typedef int32_t         SizeL;
typedef int64_t         SizeLL;

#ifndef USE_XDC
typedef uint8_t         Bits8;
typedef uint16_t        Bits16;
typedef uint32_t        Bits32;
typedef uint64_t        Bits64;
#endif

#ifndef _TI_STD_TYPES   //redefined in tistdtypes.h
typedef int8_t          Int8;
typedef uint8_t         Uint8;
typedef int16_t         Int16;
typedef uint16_t        Uint16;
typedef int32_t         Int32;
typedef uint32_t        Uint32;
typedef int64_t         Int64;
#endif
typedef uint64_t        Uint64;
//
#ifndef _TI_STD_TYPES
typedef void*           Ptr;
#endif
typedef uint32_t        PtrVal;//FIXME ?64
typedef char            Object[];
typedef Object*         Obj;

typedef uint32_t        RegVal;
typedef volatile RegVal Mmr;
typedef Mmr*            RegPtr;

typedef uint32_t        NanoSecond;
typedef uint64_t        Timestamp;

typedef Int8            Priority;
typedef void*           Argv[];

/* system id have same code method with system code, this identifier
 * an object(progress, sem... listed in System_Module) in system. */
typedef Uint16          Sid;

typedef union {
    Uint8 str[4];
    Uint32 val;         } Name;

typedef union {
    Uint8  Hex[4];
    Uint8  Byte[4];
    Uint16 DByte[2];
    Uint32 QByte;       } Union32;

static inline
Uint32
Type_QByteVal(
    Uint8 msByteA,
    Uint8   byteB,
    Uint8   byteC,
    Uint8 lsByteD
){
    Union32 var;
    var.Byte[0] = msByteA;
    var.Byte[1] = byteB;
    var.Byte[2] = byteC;
    var.Byte[3] = lsByteD;

    return var.QByte;
}

typedef union {
    Uint8  Hex[8];
    Uint8  Byte[8];
    Uint16 DByte[4];
    Uint32 QByte[2];
    Uint64 OByte;       } Union64;


/* ? CONST VAR ? */
#define IN      /* input argument */
#define OU      /* output argument */
#define IO      /* in/out put argument*/

#define WAIT_NONE       0
#define WAIT_FOREVER    -1

#define ENABLE          1
#define DISABLE         0

#define YES             1U
#define NO              0

#define NONE            0
#define ANY             -1
#define ALL             -1

#define OK              0
#define FAIL            -1

#define VALID           1
#define INVALID         -1

#define EOF_LN  ;

//#define _STR(S)       #S
#define _BIT(x)         (1 << x)
#define _SELF           0


typedef enum {
    Loopback_NO,
    Loopback_DIGITAL,
    Loopback_SERDES_LANE,
    Loopback_EXT_LINK,
    Loopback_EXT_FORWARD,
    Loopback_EXT_ECHO,
    Loopback_MAX_MODE,
    Loopback_INVALID
} Loopback;


//TODO add impl.
#define SWAP_H8 (b8)     //TODO add
#define SWAP_B16(b16)   (((b16 & 0x00FF) << 8) | (b16 >>8))
#define SWAP_B32(b32)   ((((Uint32)(b32) & 0xff000000) >> 24) | \
                         (((Uint32)(b32) & 0x00ff0000) >>  8) | \
                         (((Uint32)(b32) & 0x0000ff00) <<  8) | \
                         (((Uint32)(b32) & 0x000000ff) << 24) )
#define SWAP_B64(b64)     //TODO add

#if (ENDIAN == _BE)
#define BE16(v) (v)
#define BE32(v) (v)
#define BE64(v) (v)
#else
#define BE16(v) SWAP_B16(v)
#define BE32(v) SWAP_B32(v)
#define BE64(v) SWAP_B64(v)
#endif

//round up & down, A must be power of 2
#define ROUND_DN(V, A)  (V & ~(A -1))
#define ROUND_UP(V, A)  ((V + (A-1)) & ~(A -1))

#ifndef _DBG
#define NDEBUG  //disable assert
#define STATIC static
#define assert(_expr)   do {} while (0)
#else
#include <assert.h>
#define STATIC
#endif


/* attributes */
#define __weak              __attribute__ ((weak))
#define __init              __attribute__((section(".text.init")))
#define __knl(type)         __attribute__((section("."#type".knl")))
#define __aid(name)         __attribute__((section(".text.aid:"#name)))
#define __data(type)         __attribute__((section(".data."#type)))
#define __daemon(name)      __attribute__((section(".text.daemon:"#name)))
#define __firmware(name)    __attribute__((section(".const.firmware:"#name)))
#define __buffer(name)      __attribute__((aligned(32), section(".far.buffer:"#name)))
#define __descriptor(name)  __attribute__((aligned(32), section(".far.descriptor:"#name)))
//#define __section(sect) __attribute__((section(#sect)))
//#define __packed
//#define __alignof(a)

/* System used type */
typedef void*       Process_Id;
typedef int (*Printf)(const char* fmt, ...);


/* Log support as default */
#include <Log.h>

#endif /* INCLUDE_TYPE_H_ */
